﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GRTVPluginConsole.Entity;

namespace GRTVPluginConsole.Camera
{
    class CycleTopDriversPerCategoryCamera:AutoCameraEngine
    {
        int viewedSlotId = -1;
        int cameraType;
        bool excludePit;
        int frequencySecond;
        int nbDrivers;
        long lastCameraChange;
        Dictionary<string, List<DriverRank>> driversPerCategory;
        List<String> categories;
        public CycleTopDriversPerCategoryCamera(int cameraType, bool excludePit, int frequencySecond, int nbDrivers)
            : base()
        {
            this.cameraType = cameraType;
            this.excludePit = excludePit;
            this.frequencySecond = frequencySecond;
            this.nbDrivers = nbDrivers;
            driversPerCategory = new Dictionary<string, List<DriverRank>>();
            categories = new List<String>();
        }

        public override void DoCheck()
        {
            if (DateTime.Now.Ticks - lastCameraChange >= frequencySecond * 10000000)
            {
                if (Program.DriverList.Count > 0)
                {
                    lastCameraChange = DateTime.Now.Ticks;
                    driversPerCategory.Clear();
                    categories.Clear();
                    // collect drivers per categorie
                    int indexCategoryViewed = -1;
                    int indexDriverViewed = -1;
                    for (int i = 0; i < Program.DriverList.Count; i++)
                    {
                        DriverRank dr = Program.DriverList[i];
                        if (dr != null)
                        {
                            List<DriverRank> drs = null;
                            int catIndex = categories.IndexOf(dr.categoryGroup);
                            if (catIndex == -1)
                            {
                                catIndex = categories.Count;
                                categories.Add(dr.categoryGroup);
 
                                drs = new List<DriverRank>();
                                driversPerCategory[dr.categoryGroup] = drs;
                            }
                            else
                            {
                                drs = driversPerCategory[dr.categoryGroup];
                            }
                            drs.Add(dr);
                            if (viewedSlotId == dr.slotId)
                            {
                                indexCategoryViewed = catIndex;
                                indexDriverViewed = drs.Count - 1;
                            }
                        }
                    }
                    // search current viewed driver index
                    int currCatIndex = Math.Max(0, indexCategoryViewed); // set to 0 in case of first activation of the camera
                    int currDriverIndex = indexDriverViewed; // can be -1 for the first activation of the camera

                    for (int iCat = 0; iCat < categories.Count; iCat++)
                    {
                        List<DriverRank> drivers = driversPerCategory[categories[currCatIndex % categories.Count]];
                        for (int iDriver = 0; iDriver < drivers.Count; iDriver++)
                        {
                            currDriverIndex++;
                            if (currDriverIndex >= drivers.Count || currDriverIndex >= nbDrivers)
                            {
                                break;
                            }
                            else
                            {
                                DriverRank dr = drivers[currDriverIndex];
                                if (dr != null && (!excludePit || !dr.isInPit) && dr.finishStatus <= 1)
                                {
                                    viewedSlotId = dr.slotId;
                                    Program.ViewDriver(viewedSlotId, cameraType);
                                    return;
                                }
                            }
                        }
                        currDriverIndex = -1;
                        currCatIndex++;
                    }
                }
            }
        }

        public override void Reset()
        {
            viewedSlotId = -1;
            lastCameraChange = 0;
        }
    }
}
